package com.cookor.poi.modules.weixin.account;

import com.cookor.poi.common.utils.IdGen;
import com.cookor.poi.common.utils.SpringContextHolder;
import com.cookor.poi.modules.weixin.entity.TWeixinConfig;
import com.cookor.poi.modules.weixin.entity.WeixinUser;
import com.cookor.poi.modules.weixin.pojo.Menu;
import com.cookor.poi.modules.weixin.service.TWeixinConfigService;
import com.cookor.poi.modules.weixin.service.WeixinUserService;
import com.cookor.poi.utils.CacheFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.xiaoleilu.hutool.crypto.SecureUtil;
import com.xiaoleilu.hutool.http.HttpUtil;
import com.xiaoleilu.hutool.json.JSONArray;
import com.xiaoleilu.hutool.json.JSONObject;
import com.xiaoleilu.hutool.json.JSONUtil;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class Account {

	private final static Logger logger = Logger.getLogger(Account.class);
	private static TWeixinConfigService weixinConfigService = SpringContextHolder
			.getBean(TWeixinConfigService.class);

	protected TWeixinConfig weixinConfig;
	// 获取access_token
	private static final String WEIXIN_API_ACCESSTOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
	// access_token凭证有效时间
	private static final int WEIXIN_API_ACCESSTOKEN_EXPIRES_IN = 7000;
	// 自定义菜单创建接口
	private static final String WEIXIN_API_CREATEMENU = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=%s";
	// 自定义菜单删除接口
	private static final String WEIXIN_API_DELETEMENU = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=%s";
	// 自定义菜单查询接口
	private static final String WEIXIN_API_QUERYMENU = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=%s";
	/***** 获取用户基本信息 ******/
	// 获取用户基本信息
	private static final String WEIXIN_API_USERINFO = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN";
	// 批量获取用户基本信息
	private static final String WEIXIN_API_BATCHGET = "https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=%s";
	// 生成带参数的二维码
	private static final String WEIXIN_API_QRCORD = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=%s";

	// 获取用户列表
	private static final String WEIXIN_API_USERLIST = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=%s&next_openid=%s";
	/***** 获取用户基本信息 ******/
	// 获取用户增减数据
	// https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141082&token=&lang=zh_CN
	private static final String WEIXIN_API_USERSUMMARY = "https://api.weixin.qq.com/datacube/getusersummary?access_token=%s";
	// 获取累计用户数据
	// https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141082&token=&lang=zh_CN
	private static final String WEIXIN_API_USERCUMULATE = "https://api.weixin.qq.com/datacube/getusercumulate?access_token=%s";

	private static final String WEIXIN_API_JSAPI = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi";
	// 长地址转成短地址
	private static final String WEIXIN_API_LONG2SHORT = "https://api.weixin.qq.com/cgi-bin/shorturl?access_token=%s";
	/********** 用户标签管理 ***********/
	// 创建标签
	private static final String WEIXIN_API_CREATETAG = "https://api.weixin.qq.com/cgi-bin/tags/create?access_token=%s";
	// 获取公众号已创建的标签
	private static final String WEIXIN_API_GETTAG = "https://api.weixin.qq.com/cgi-bin/tags/get?access_token=%s";
	// 编辑标签
	private static final String WEIXIN_API_UPDATETAG = "https://api.weixin.qq.com/cgi-bin/tags/update?access_token=%s";
	// 删除标签
	private static final String WEIXIN_API_DELETETAG = "https://api.weixin.qq.com/cgi-bin/tags/delete?access_token=%s";
	// 获取标签下粉丝列表
	private static final String WEIXIN_API_GETTAGUSER = "https://api.weixin.qq.com/cgi-bin/user/tag/get?access_token=%s";
	// 批量为用户打标签
	private static final String WEIXIN_API_BATCHTAG = "https://api.weixin.qq.com/cgi-bin/tags/members/batchtagging?access_token=%s";
	// 批量为用户取消标签
	private static final String WEIXIN_API_BATCHUNTAG = "https://api.weixin.qq.com/cgi-bin/tags/members/batchuntagging?access_token=%s";
	// 获取用户身上的标签列表
	private static final String WEIXIN_API_GETIDLIST = "https://api.weixin.qq.com/cgi-bin/tags/getidlist?access_token=%s";
	// 设置用户备注名
	private static final String WEIXIN_API_UPDATEREMARK = "https://api.weixin.qq.com/cgi-bin/user/info/updateremark?access_token=%s";
	/********** 用户标签管理 ***********/

	/******** 黑名单管理 *************/
	// 获取公众号的黑名单列表
	private static final String WEIXIN_API_GETBLACKLIST = "https://api.weixin.qq.com/cgi-bin/tags/members/getblacklist?access_token=%s";
	// 拉黑用户
	private static final String WEIXIN_API_BATCHBLACKLIST = "https://api.weixin.qq.com/cgi-bin/tags/members/batchblacklist?access_token=%s";
	// 取消拉黑用户
	private static final String WEIXIN_API_BATCHUNBLACKLIST = "https://api.weixin.qq.com/cgi-bin/tags/members/batchunblacklist?access_token=%s";
	/******** 黑名单管理 *************/
	// 公众号的所有API调用（包括第三方代公众号调用）次数进行清零
	private static final String WEIXIN_API_CLEAR_QUOTA = "https://api.weixin.qq.com/cgi-bin/clear_quota?access_token=%s";

	// 请求CODE
	private static final String WEIXIN_API_OAUTH_CODE = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect";
	// 通过code换取access_token
	private static final String WEIXIN_API_OAUTH_INFO = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
	// 通过code换取access_token
	private static final String WEIXIN_API_OAUTH_USERINFO = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN";
	// 发送模板消息
	private static final String WEIXIN_API_TEMPLATE_SEND = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";
	// 授权登陆地址
	private static final String WEIXINPLATFORM_API_CUSTOM_SEND = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s";

	//上传图片
	private static final String WEIXIN_API_UPLOADIMG="https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=%s";

	public Account(TWeixinConfig weixinConfig) {
		this.weixinConfig = weixinConfig;
	}

	public TWeixinConfig getWeixinConfig() {
		return weixinConfig;
	}

	public void setWeixinConfig(TWeixinConfig weixinConfig) {
		this.weixinConfig = weixinConfig;
	}

	public static Account factory(String id) {
		TWeixinConfig weixinConfig = weixinConfigService.get(id);
//		return factory(weixinConfig);
		return new Account(weixinConfig);
	}

//	public static Account factory(WeixinConfig weixinConfig) {
//		if (weixinConfig.getType() == 3) {
//			return new PlatformAccount(weixinConfig);
//		} else {
//			return new Account(weixinConfig);
//		}
//	}

	public static JSONObject httpGet(String url) {
		logger.debug("request：" + url);
		String result = HttpUtil.get(url);
		logger.debug("response：\n" + result);
		return JSONUtil.parseObj(result);
	}

	public static JSONObject httpGet(String url, Map<String, Object> paramMap) {
		// logger.debug("request：" + url);
		// logger.debug("参数"+paramMap);
		String result = HttpUtil.get(url, paramMap);
		// logger.debug("response：\n" + result);
		return JSONUtil.parseObj(result);
	}

	public static JSONObject httpPost(String url, Map<String, Object> paramMap) {
		logger.debug("request：" + url);
		logger.debug("参数" + paramMap);
		String result = HttpUtil.post(url, paramMap);
		logger.debug("response1：\n" + result);
		return JSONUtil.parseObj(result);
	}

	public static JSONObject httpPost(String url, String data) {
		logger.debug("request：" + url);
		logger.debug("参数:" + data);
		String result = HttpUtil.post(url, data);
		logger.debug("response：\n" + result);
		return JSONUtil.parseObj(result);
	}

	public JSONObject clearQuota() throws WeixinException {
		String url = String.format(WEIXIN_API_CLEAR_QUOTA, getAccessToken());
		return httpGet(url);
	}

	public JSONObject updateRemark(String openid, String remark)
			throws WeixinException {
		String url = String.format(WEIXIN_API_UPDATEREMARK, getAccessToken());
		Map<String, Object> params = Maps.newConcurrentMap();
		params.put("openid", openid);
		params.put("remark", remark);
		return httpPost(url, JSONUtil.toJsonStr(params));
	}

	public JSONObject createTag(String name) throws WeixinException {
		String url = String.format(WEIXIN_API_CREATETAG, getAccessToken());
		Map<String, Object> params = Maps.newConcurrentMap();
		Map<String, Object> params2 = Maps.newConcurrentMap();
		params.put("name", name);
		params2.put("tag", params);
		return httpPost(url, JSONUtil.toJsonStr(params2));
	}

	public JSONObject getTags() throws WeixinException {
		String url = String.format(WEIXIN_API_GETTAG, getAccessToken());
		return httpGet(url);
	}

	public JSONObject updateTag(String id, String name) throws WeixinException {
		String url = String.format(WEIXIN_API_UPDATETAG, getAccessToken());
		Map<String, String> map = Maps.newConcurrentMap();
		map.put("id", id);
		map.put("name", name);
		Map<String, Object> params = Maps.newConcurrentMap();
		params.put("tag", map);
		return httpPost(url, JSONUtil.toJsonStr(params));
	}

	public JSONObject deleteTag(String id) throws WeixinException {
		String url = String.format(WEIXIN_API_DELETETAG, getAccessToken());
		Map<String, String> map = Maps.newConcurrentMap();
		Map<String, Object> params = Maps.newConcurrentMap();
		map.put("id", id);
		params.put("tag", map);
		return httpPost(url, JSONUtil.toJsonStr(params));
	}

	public JSONObject getTagUser(String tagid, String nextOpenid)
			throws WeixinException {
		Map<String, String> map = Maps.newConcurrentMap();
		if (StringUtils.isNotEmpty(nextOpenid)) {
			map.put("next_openid", nextOpenid);
		}
		map.put("tagid", tagid);
		String url = String.format(WEIXIN_API_GETTAGUSER, getAccessToken());
		Map<String, Object> params = Maps.newConcurrentMap();
		params.put("tag", map);
		return httpPost(url, JSONUtil.toJsonStr(params));
	}

	public JSONObject getUserSummary(String beginDate, String endDate) throws WeixinException{
		String url = String.format(WEIXIN_API_USERSUMMARY, getAccessToken());
		Map<String, String> map = Maps.newConcurrentMap();
		map.put("begin_date", beginDate);
		map.put("end_date", endDate);
		return httpPost(url, JSONUtil.toJsonStr(map));
	}

	public JSONObject getUserCumulate(String beginDate, String endDate) throws WeixinException{
		String url = String.format(WEIXIN_API_USERCUMULATE, getAccessToken());
		Map<String, String> map = Maps.newConcurrentMap();
		map.put("begin_date", beginDate);
		map.put("end_date", endDate);
		return httpPost(url, JSONUtil.toJsonStr(map));
	}

	public JSONObject batchTag(List<String> openid_list, String tagid)
			throws WeixinException {
		String url = String.format(WEIXIN_API_BATCHTAG, getAccessToken());
		Map<String, Object> params = Maps.newConcurrentMap();
		params.put("openid_list", openid_list);
		params.put("tagid", tagid);
		return httpPost(url, JSONUtil.toJsonStr(params));
	}

	public JSONObject batchUnTag(List<String> openid_list, String tagid)
			throws WeixinException {
		String url = String.format(WEIXIN_API_BATCHUNTAG, getAccessToken());
		Map<String, Object> params = Maps.newConcurrentMap();
		params.put("openid_list", openid_list);
		params.put("tagid", tagid);
		return httpPost(url, JSONUtil.toJsonStr(params));
	}

	public JSONObject getTagIdList(String openid) throws WeixinException {
		String url = String.format(WEIXIN_API_GETIDLIST, getAccessToken());
		Map<String, Object> params = Maps.newConcurrentMap();
		params.put("openid", openid);
		return httpPost(url, JSONUtil.toJsonStr(params));
	}

	public JSONObject sendCustom(Map<String, Object> paramsMap)
			throws WeixinException {
		String url = String.format(WEIXINPLATFORM_API_CUSTOM_SEND,
				getAccessToken());
		return httpPost(url, paramsMap);
	}

	public static JSONObject sendCustom(String token,
                                        Map<String, Object> paramsMap) {
		String url = String.format(WEIXINPLATFORM_API_CUSTOM_SEND, token);
		// Map<String,Object> map =(Map<String,Object>)paramsMap.get("text");
		// String str="{\"touser\":\""+paramsMap.get("touser")+"\",";
		// str+="\"msgtype\":\"text\",";
		// str+="\"text\":{\"content\":\""+map.get("content")+"\"}}";
		String str = JSONUtil.toJsonStr(paramsMap);
		return httpPost(url, str);
	}

	public static JSONObject getOauthUserInfo(String token, String openid) {
		String url = String.format(WEIXIN_API_OAUTH_USERINFO, token, openid);
		return httpGet(url);
	}

	public JSONObject getUserInfo(String openid) throws WeixinException {
		String url = String.format(WEIXIN_API_OAUTH_USERINFO, getAccessToken(),
				openid);
		return httpGet(url);
	}

	public WeixinUser getWeixinUser(String openid) throws WeixinException {
		JSONObject jsonObject = getUserInfo(openid);
		WeixinUser user = WeixinUserService.jsonToWeixinUser(jsonObject);
		String subscribeTime = jsonObject.getStr("subscribe_time");
		if (StringUtils.isNoneBlank(subscribeTime)) {
			user.setSubscribeTime(Long.valueOf(subscribeTime));
			user.setFirstTime(Long.valueOf(subscribeTime));
			String tags = jsonObject.getStr("tagid_list");
			if (StringUtils.isNotBlank(tags) && tags.length() > 2) {
				user.setTagidList(tags.substring(1, tags.length() - 1));
			}
		}
		return user;
	}

	public static JSONObject getOauthInfo(String code, String appid,
                                          String secret) {
		String url = String.format(WEIXIN_API_OAUTH_INFO, appid, secret, code);
		return httpGet(url);
	}

	public JSONObject getOauthInfo(String code) throws WeixinTicketNotFoundException {
		return getOauthInfo(code, weixinConfig.getAppid(),
				weixinConfig.getSecret());
	}

	public String getOauthCodeUrl(String callbackurl, String state, String scope)
			throws UnsupportedEncodingException {
		if (StringUtils.isBlank(scope)) {
			scope = "snsapi_base";
		}
		String redirect_uri = URLEncoder.encode(callbackurl, "utf-8");
		return String.format(WEIXIN_API_OAUTH_CODE, weixinConfig.getAppid(),
				redirect_uri, scope, state);
	}

	public JSONObject createMenu(Menu menu) throws WeixinException {
		String token = getAccessToken();
		String strJson = JSONUtil.toJsonStr(menu);
		String url = String.format(WEIXIN_API_CREATEMENU, token);
		return httpPost(url, strJson);
	}

	public JSONObject deleteMenu() throws WeixinException {
		String token = getAccessToken();
		String url = String.format(WEIXIN_API_CREATEMENU, token);
		return httpGet(url);
	}

	public JSONObject modifyMenu(Menu menu) throws WeixinException {
		return createMenu(menu);
	}

	public JSONObject queryMenu() throws WeixinException {
		String token = getAccessToken();
		String url = String.format(WEIXIN_API_QUERYMENU, token);
		return httpGet(url);
	}

	public JSONObject batchgetUserInfo(String[] list) throws WeixinException {
		List<Map<String, String>> dataList = Lists.newArrayList();
		Map<String, String> map = Maps.newConcurrentMap();
		for (String openid : list) {
			map.put("openid", openid);
			map.put("lang", "zh-CN");
			dataList.add(map);
		}
		return batchgetUserInfo(dataList);
	}

	public JSONObject batchgetUserInfo(List<Map<String, String>> list)
			throws WeixinException {
		String token = getAccessToken();
		String url = String.format(WEIXIN_API_BATCHGET, token);
		Map<String, Object> params = Maps.newConcurrentMap();
		params.put("user_list", list);
		return httpPost(url, JSONUtil.toJsonStr(params));
	}

	public List<WeixinUser> batchgetWeixinUser(List<Map<String, String>> list)
			throws WeixinException {
		JSONObject jsonObject = batchgetUserInfo(list);
		JSONArray ja = JSONUtil.parseArray(jsonObject.getStr("user_info_list"));
		List<WeixinUser> weixinUserlist = Lists.newArrayList();
		for (int i = 0; i < ja.size(); i++) {
			JSONObject jo = ja.getJSONObject(i);
			WeixinUser weixinUser = JSONUtil.toBean(jo, WeixinUser.class);
			weixinUserlist.add(weixinUser);
		}
		return weixinUserlist;
	}

	public JSONObject fansAll(String nextOpenid) throws WeixinException {
		String token = getAccessToken();
		String url = String.format(WEIXIN_API_USERLIST, token,nextOpenid);
		return httpGet(url);
	}

	//创建临时二维码
		public JSONObject createQRScene(int expire_seconds, String scene_id) throws WeixinException{
			String token = getAccessToken();
			String url = String.format(WEIXIN_API_QRCORD,token);
			String data = "{\"expire_seconds\": "+expire_seconds+", \"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": "+scene_id+"}}}";
			return httpPost(url,data);
		}
		//永久二维码
		public JSONObject createQRlimitSceneBySceneId(String scene_id) throws WeixinException{
			String token = getAccessToken();
			String url = String.format(WEIXIN_API_QRCORD,token);
			String data = "{\"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": "+scene_id+"}}}";
			return httpPost(url,data);
		}
		//永久二维码
		public JSONObject createQRlimitSceneBySceneStr(String scene_str)
				throws WeixinException {
			String token = getAccessToken();
			String url = String.format(WEIXIN_API_QRCORD, token);
			String data = "{\"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": "
					+ scene_str + "}}}";
			return httpPost(url, data);
		}
	public static String getOuathAccessToken(String appid, String appSercet, String code){
		String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+ appid + "&secret=" +
				appSercet + "&code=" + code + "&grant_type=authorization_code";
		JSONObject jsonObject = httpGet(url);
		logger.error("jo:"+jsonObject.toString());
		return jsonObject.getStr("access_token");
	}
	public String getAccessToken() throws WeixinException {
		String cachename = "accesstoken";
		String cachekey = weixinConfig.getAppid();
		String accessToken = null;
		Map<String, String> map = (Map<String, String>) CacheFactory
				.get(cachename);
		if (isUseCache(map)) {
			String url = String.format(WEIXIN_API_ACCESSTOKEN,
					weixinConfig.getAppid(), weixinConfig.getSecret());
			JSONObject jsonObject = httpGet(url);
			accessToken = jsonObject.getStr("access_token");
			String expires_in = jsonObject.getStr("expires_in");
			map = Maps.newConcurrentMap();
			map.put("access_token", accessToken);
			map.put("expires_in", expires_in);
			if (StringUtils.isBlank(accessToken)) {
				String msg = "获取微信公众号授权失败, 请稍后重试！ 公众平台返回原始数据为: 错误代码-"
						+ jsonObject.getStr("errcode") + "，错误信息-"
						+ jsonObject.getStr("errmsg");
				throw new WeixinException(msg);
			}
			CacheFactory.put(cachename, cachekey, map,
					WEIXIN_API_ACCESSTOKEN_EXPIRES_IN, -1);
			return accessToken;
		}
		return map.get("access_token");
	}

	public String getJsApiTicket() throws WeixinException {
		String cacheKey = "jsticket:" + weixinConfig.getAppid();
		String ticket = (String) CacheFactory.get(cacheKey);
		String accessToken = getAccessToken();
		if (StringUtils.isNotBlank(ticket)) {
			System.out.println("ssss:" + ticket);
			return ticket;
		} else {

			String url = String.format(WEIXIN_API_JSAPI, accessToken);
			System.out.println("url:" + url);
			JSONObject jsonObject = httpGet(url);
			ticket = jsonObject.getStr("ticket");
			if (StringUtils.isBlank(ticket)) {
				String msg = "调用接口获取微信公众号 jsapi_ticket 失败, 错误信息: "
						+ jsonObject.getStr("errcode") + "，错误信息-"
						+ jsonObject.getStr("errmsg");
				System.out.println("msg" + msg);
				throw new WeixinException(msg);
			} else {
				CacheFactory.put(cacheKey, ticket,
						WEIXIN_API_ACCESSTOKEN_EXPIRES_IN);
				return ticket;
			}
		}
	}

	public Map<String, String> getJssdkConfig(String url)
			throws WeixinException {
		String jsapiTicket = getJsApiTicket();
		String nonceStr = IdGen.getRandomStringByLength(16);
		Date now = new Date();
		String timestamp = "" + (now.getTime() / 1000);

		String source = "jsapi_ticket=" + jsapiTicket + "&noncestr=" + nonceStr
				+ "&timestamp=" + timestamp + "&url=" + url;
		System.out.println("source:" + source);
		String signature = SecureUtil.sha1(source);
		Map<String, String> map = Maps.newConcurrentMap();
		map.put("appId", weixinConfig.getAppid());
		map.put("nonceStr", nonceStr);
		map.put("timestamp", timestamp);
		map.put("signature", signature);
		return map;
	}

	public String long2short(String longUrl) throws WeixinException {
		String token = getAccessToken();
		Map<String, Object> params = Maps.newConcurrentMap();
		params.put("access_token", token);
		params.put("action", "long2short");
		params.put("long_url", longUrl);
		JSONObject jsonObject = httpGet(WEIXIN_API_LONG2SHORT, params);
		String errcode = jsonObject.getStr("errcode");
		if ("0".equals(errcode)) {
			return jsonObject.getStr("short_url");
		} else {
			String msg = "访问微信接口错误, 错误代码: " + jsonObject.getStr("errcode")
					+ "，错误信息-" + jsonObject.getStr("errmsg");
			throw new WeixinException(msg);
		}
	}

	public JSONObject sendCustomNotice(Map<String, Object> data)
			throws WeixinException {
		String url = String.format(WEIXIN_API_TEMPLATE_SEND, getAccessToken());
		return httpPost(url, data);
	}

	public static boolean isUseCache(Map<String, String> map) {
		long TIMESTAMP = System.currentTimeMillis() / 1000;
		return map == null || StringUtils.isBlank(map.get("value"))
				|| Integer.valueOf(map.get("expire")) < TIMESTAMP;
	}

	public JSONObject uploadimg() throws WeixinException{
		String token = getAccessToken();
		String url = String.format(WEIXIN_API_UPLOADIMG, token);
		return null;
	}

	public static void main(String[] agrs) {
		/*
		 * String str = "{\"user_info_list\": ["; str += "{"; str +=
		 * "\"subscribe\": 1, "; str +=
		 * "\"openid\": \"otvxTs4dckWG7imySrJd6jSi0CWE\", "; str +=
		 * "\"nickname\": \"iWithery\", "; str += "\"sex\": 1, "; str +=
		 * "\"language\": \"zh_CN\", "; str += " \"city\": \"Jieyang\", "; str
		 * += " \"province\": \"Guangdong\", "; str +=
		 * " \"country\": \"China\", "; str +=
		 * " \"headimgurl\": \"http://wx.qlogo.cn/mmopen/xbIQx1GRqdvyqkMMhEaGOX802l1CyqMJNgUzKP8MeAeHFicRDSnZH7FY4XB7p8XHXIf6uJA2SCunTPicGKezDC4saKISzRj3nz/0\","
		 * ; str += " \"subscribe_time\": 1434093047, "; str +=
		 * " \"unionid\": \"oR5GjjgEhCMJFyzaVZdrxZ2zRRF4\", "; str +=
		 * " \"remark\": \"\", "; str += "  \"groupid\": 0,"; str +=
		 * "  \"tagid_list\":[128,2]"; str += "}, "; str += " {"; str +=
		 * "    \"subscribe\": 0, "; str +=
		 * "   \"openid\": \"otvxTs_JZ6SEiP0imdhpi50fuSZg\", "; str +=
		 * "     \"unionid\": \"oR5GjjjrbqBZbrnPwwmSxFukE41U\", "; str += " }";
		 * str += "]"; str += "}"; JSONObject jsonObject =
		 * JSONUtil.parseObj(str); JSONArray ja =
		 * JSONUtil.parseArray(jsonObject.getStr("user_info_list"));
		 * List<WeixinUser> list = Lists.newArrayList(); for(int i
		 * =0;i<ja.length();i++){ JSONObject jo = ja.getJSONObject(i);
		 * WeixinUser weixinUser = JSONUtil.toBean(jo, WeixinUser.class);
		 * list.add(weixinUser); }
		 *
		 * System.out.println(list);
		 */
	}

}
